package com.yuxin.tongyi.lsll.util;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.res.Resources;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AbsListView;
import android.widget.AbsListView.OnScrollListener;
import android.widget.ArrayAdapter;
import android.widget.BaseAdapter;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

import com.yuxin.tongyi.lsll.R;

/**
 * 自定义日期选择组件
 * 
 * @Date 2011-12-22
 * @author ww
 * @invoke mDialog = new CustomDatePicker(CustomDatePickerActivity.this,
 *         CustomDatePicker.DateStyle.DS_YYYY_MM_DD);
 *         mDialog.setInputDate("2011-12-23"); mDialog.show();
 *         mDialog.setDateInterface(new DateInterface() { public void
 *         setDate(String sdate) { tvDate.setText(sdate); } });
 */
public class CustomDatePicker extends AlertDialog {

	private ArrayAdapter<String> adapterYear, adapterMonth, adapterDay;
	private ListView lvYear, lvMonth, lvDay;
	private String selectYear, selectMonth, selectDay;
	private List<String> listYear, listMonth, listDay;
	private String[] arrYear, arrMonth, arrDay31, arrDay30, arrDay29, arrDay28;
	private Context mContext;
	private DateStyle mDateStyle;
	private String InputDate = null; // 输入日期
	private String SelectDate; // 输出日期
	private String[] arrDate;
	private View layout;
	private MonthDays mMonthDays;
	private DateInterface mDateInterface;
	private LayoutInflater inflater;
	private Resources resources;
	private TextView dateview;
	private SimpleDateFormat sdf;
	Calendar calendar = Calendar.getInstance();

	public void setDateInterface(DateInterface DateInterface) {
		this.mDateInterface = DateInterface;
	}

	private int i_month_num, i_year_num, i_day_num;
	// listview标识
	final int CONS_YEAR_ID = 1;
	final int CONS_MONTH_ID = 2;
	final int CONS_DAY_ID = 3;

	public CustomDatePicker(Context context, DateStyle DateStyle) {
		super(context);
		
		this.mContext = context;
		this.mDateStyle = DateStyle;

		setButton(context.getText(R.string.ok), (OnClickListener) new OnBtnClickListener());
		setButton2(context.getText(R.string.cancel), (OnClickListener) null);
		inflater = getLayoutInflater();
		layout = inflater.inflate(R.layout.date_time_picker, null);
		setView(layout);
		setTitle("请选择日期");
		resources = context.getResources();
	}

	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

		arrDate = InputDate.split("-");
		selectYear = arrDate[0];
		selectMonth = arrDate[1];
		selectDay = arrDate[2];

		// 判断输出日期类型
		switch (mDateStyle) {
		case DS_YYYY_MM_DD:
			setYear();
			setMonth();
			setDay();

			break;
		case DS_YYYY_MM:
			setYear();
			setMonth();
			layout.findViewById(R.id.LayoutDay).setVisibility(View.GONE);
			break;
		case DS_YYYY:
			setYear();
			layout.findViewById(R.id.LayoutMonth).setVisibility(View.GONE);
			layout.findViewById(R.id.LayoutDay).setVisibility(View.GONE);
			break;
		default:
			setYear();
			setMonth();
			setDay();
			break;
		}
	}
	
	public void setYear() {
		lvYear = (ListView) findViewById(R.id.listViewYear);
		lvYear.setDivider(null);
		if(arrYear==null||arrYear.length==0){
			arrYear = resources.getStringArray(R.array.year);
		}
		i_year_num = arrYear.length;
		listYear = Arrays.asList(arrYear);
		
		DateAdapter adapterYear = new DateAdapter(mContext, CONS_YEAR_ID, null);
		lvYear.setAdapter(adapterYear);
		lvYear.setOnScrollListener(new OnlvScrollListener(CONS_YEAR_ID));

		int index = listYear.indexOf(selectYear);
		lvYear.setSelection(index + i_year_num*10 - 2);
	}

	public void setMonth() {
		lvMonth = (ListView) findViewById(R.id.listViewMonth);
		lvMonth.setDivider(null);
		arrMonth = resources.getStringArray(R.array.month);
		i_month_num = arrMonth.length;
		listMonth = Arrays.asList(arrMonth);

		DateAdapter adapterMonth = new DateAdapter(mContext, CONS_MONTH_ID, null);
		lvMonth.setAdapter(adapterMonth);

		lvMonth.setOnScrollListener(new OnlvScrollListener(CONS_MONTH_ID));
		int index = listMonth.indexOf(selectMonth);
		lvMonth.setSelection(index + i_month_num*50 - 2);
	}

	public void setDay() {
		lvDay = (ListView) findViewById(R.id.listViewDay);
		lvDay.setDivider(null);
		setDayList(selectYear, selectMonth);
		lvDay.setOnScrollListener(new OnlvScrollListener(CONS_DAY_ID));
	}

	public void setDayList(String sYear, String sMonth) {
//		int iSelectYear = Integer.parseInt(sYear);
//		int iSelectMonth = Integer.parseInt(sMonth);
		//mMonthDays = getMonthDays(iSelectYear, iSelectMonth);
		int iDays = getMonthDays(sYear, sMonth);
		switch (iDays) {
		case 31:
			arrDay31 = resources.getStringArray(R.array.day31);
			i_day_num = arrDay31.length;
			listDay = Arrays.asList(arrDay31);
			mMonthDays = MonthDays.CONS_DAY_31;
			break;
		case 30:
			arrDay30 = resources.getStringArray(R.array.day30);
			i_day_num = arrDay30.length;
			listDay = Arrays.asList(arrDay30);
			mMonthDays = MonthDays.CONS_DAY_30;
			break;
		case 29:
			arrDay29 = resources.getStringArray(R.array.day29);
			i_day_num = arrDay29.length;
			listDay = Arrays.asList(arrDay29);
			mMonthDays = MonthDays.CONS_DAY_29;
			break;
		case 28:
			arrDay28 = resources.getStringArray(R.array.day28);
			i_day_num = arrDay28.length;
			listDay = Arrays.asList(arrDay28);
			mMonthDays = MonthDays.CONS_DAY_28;
			break;
		}

		DateAdapter adapterDay = new DateAdapter(mContext, CONS_DAY_ID, mMonthDays);
		lvDay.setAdapter(adapterDay);
		
		int index;
		// 如果选中年月中没有这一天，自动跳到选中年月的最后一天
		if (Integer.parseInt(selectDay) > i_day_num) {
			index = listDay.indexOf(i_day_num + "");
		} else {
			index = listDay.indexOf(selectDay);
		}
		index = index + i_day_num*30;
		lvDay.setSelection(index - 2);
		selectDay = lvDay.getItemAtPosition(index).toString();
	}

	class OnlvScrollListener implements OnScrollListener {

		private int DateFlag;

		public OnlvScrollListener(int DateFlag) {
			this.DateFlag = DateFlag;
		}

		public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
		}

		public void onScrollStateChanged(AbsListView view, int scrollState) {
			switch (scrollState) {
			case OnScrollListener.SCROLL_STATE_IDLE:
				int h = view.getHeight();
				int m = h / 2;
				int ifirst = view.getFirstVisiblePosition();
				//int ilast = view.getLastVisiblePosition();
				int icount = view.getChildCount();

				for (int i = 0; i < icount; i++) {
					int itop = view.getChildAt(i).getTop();
					int ibottom = view.getChildAt(i).getBottom();

					if (m >= itop && m <= ibottom) {
						int pos = ifirst + i;
						switch (DateFlag) {
						case CONS_YEAR_ID:
							selectYear = view.getItemAtPosition(pos).toString();
							if (mDateStyle == DateStyle.DS_YYYY_MM_DD) {
								setDayList(selectYear, selectMonth);
							}
							break;
						case CONS_MONTH_ID:
							selectMonth = view.getItemAtPosition(pos).toString();
							 if(mDateStyle==DateStyle.DS_YYYY_MM_DD){
								 setDayList(selectYear, selectMonth);
							 }
							break;
						case CONS_DAY_ID:
							selectDay = view.getItemAtPosition(pos).toString();
							break;
						}
						view.setSelection(pos - 2);
						break;
					}
				}
				break;
			case OnScrollListener.SCROLL_STATE_FLING:
				break;
			case OnScrollListener.SCROLL_STATE_TOUCH_SCROLL:
				break;
			}
		}
	}

	class OnBtnClickListener implements OnClickListener {

		public void onClick(DialogInterface dialog, int which) {
			// 判断输出日期类型
			switch (mDateStyle) {
			case DS_YYYY_MM_DD:
				SelectDate = selectYear + "-" + selectMonth + "-" + selectDay;
				break;
			case DS_YYYY_MM:
				SelectDate = selectYear + "-" + selectMonth;
				break;
			case DS_YYYY:
				SelectDate = selectYear;
				break;
			default:
				SelectDate = selectYear + "-" + selectMonth + "-" + selectDay;
				break;
			}
			if (mDateInterface != null) {
				mDateInterface.setDate(SelectDate);
			}
		}

	}

	public String getInputDate() {
		return InputDate;
	}

	public void setInputDate(String inputDate) {
		if (inputDate == null || "".equals(inputDate)) {
			sdf = new SimpleDateFormat("yyyy-MM-dd");
			InputDate = sdf.format(new Date());
		} else {
			Boolean b = isValidDate(inputDate);
			if (b) {
				InputDate = inputDate;
			} else {
				Toast.makeText(mContext, "输入日期格式错误", Toast.LENGTH_SHORT).show();
				SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
				InputDate = sdf.format(new Date());
			}
		}
	}

	// 输出日期风格
	public static enum DateStyle {
		DS_YYYY_MM_DD, DS_YYYY_MM, DS_YYYY
	}

	// 月份类型
	public enum MonthDays {
		CONS_DAY_31, CONS_DAY_30, CONS_DAY_29, CONS_DAY_28
	}

	// 根据年月判断天数
	public int getMonthDays(String sYear, String sMonth) {
		String Date = sYear + "-" + sMonth;
		int iDays = 0;
		try {
			sdf = new SimpleDateFormat("yyyy-MM");
			calendar.setTime(sdf.parse(Date));
			iDays = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
		} catch (ParseException e) {
			e.printStackTrace();
		}
		return iDays;
	}

	// 判断输入日期是否正确yyyy-mm-dd
	public boolean isValidDate(String sDate) {
		String datePattern1 = "\\d{4}-\\d{2}-\\d{2}";
		String datePattern2 = "^((\\d{2}(([02468][048])|([13579][26]))"
				+ "[\\-\\/\\s]?((((0?[13578])|(1[02]))[\\-\\/\\s]?((0?[1-9])|([1-2][0-9])|"
				+ "(3[01])))|(((0?[469])|(11))[\\-\\/\\s]?((0?[1-9])|([1-2][0-9])|(30)))|(0?2[\\-\\/\\s]?"
				+ "((0?[1-9])|([1-2][0-9])))))|(\\d{2}(([02468][1235679])|([13579][01345789]))[\\-\\/\\s]?("
				+ "(((0?[13578])|(1[02]))[\\-\\/\\s]?((0?[1-9])|([1-2][0-9])|(3[01])))|(((0?[469])|(11))[\\-\\/\\s]?"
				+ "((0?[1-9])|([1-2][0-9])|(30)))|(0?2[\\-\\/\\s]?((0?[1-9])|(1[0-9])|(2[0-8]))))))";
		if ((sDate != null)) {
			Pattern pattern = Pattern.compile(datePattern1);
			Matcher match = pattern.matcher(sDate);
			if (match.matches()) {
				pattern = Pattern.compile(datePattern2);
				match = pattern.matcher(sDate);
				return match.matches();
			} else {
				return false;
			}
		}
		return false;
	}

	public interface DateInterface {
		public void setDate(String sdate);
	}

	class DateAdapter extends BaseAdapter {

		private Context _context;
		private int _DateFlag;
		private MonthDays _MonthDays;

		public DateAdapter(Context context, int dateFlag, MonthDays monthDays) {
			this._context = context;
			this._DateFlag = dateFlag;
			this._MonthDays = monthDays;
		}

		
		public int getCount() {
			return Integer.MAX_VALUE;
		}

		
		public Object getItem(int position) {
			return getItemText(position);
		}

		
		public long getItemId(int position) {
			return position;
		}

		
		public View getView(int position, View view, ViewGroup parent) {
			if (view == null) {
				view = inflater.inflate(R.layout.dateitem, null);
				dateview = (TextView) view.findViewById(R.id.txt_item);
				view.setTag(dateview);
			} else {
				dateview = (TextView) view.getTag();
			}

			String itemText = getItemText(position);
			dateview.setText(itemText);
			return view;
		}
		
		public String getItemText(int position){
			String result = "";
			switch (_DateFlag) {
			case CONS_YEAR_ID:
				result = arrYear[position%arrYear.length];
				break;
			case CONS_MONTH_ID:
				result = arrMonth[position%arrMonth.length];
				break;
			case CONS_DAY_ID:
				switch (_MonthDays) {
				case CONS_DAY_31:
					result = arrDay31[position%arrDay31.length];
					break;
				case CONS_DAY_30:
					result = arrDay30[position%arrDay30.length];
					break;
				case CONS_DAY_29:
					result = arrDay29[position%arrDay29.length];
					break;
				case CONS_DAY_28:
					result = arrDay28[position%arrDay28.length];
					break;
				}
				break;
			}
			return result; 
		}
	}
	
	public void setYearRange(int StartYear, int EndYear) {
		int iStartYear = 1901;
		int iEndYear = 2050;
		
		if(arrYear==null||arrYear.length==0){
			if(StartYear>1000){
				iStartYear = StartYear;
			}
			if(EndYear>1000){
				iEndYear = EndYear;
			}
			if(StartYear>=EndYear){
				iStartYear = EndYear-100;
			}
			int icount = iEndYear - iStartYear + 1;
			arrYear = new String[icount];
			for(int i=0;i<icount;i++){
				arrYear[i] = iStartYear + i + "";
			}
		}
	}
	
}
